package com.zxx.cascommon.base.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import com.zxx.cascommon.base.entity.Token;
import org.springframework.util.ObjectUtils;
import sun.security.provider.MD5;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * jwt token生成工具类
 *
 * @author zhoukai
 * @date 2019/1/31 14:39
 */
public class JwtTokenUtils {

    /**
     * token秘钥，请勿泄露，请勿随便修改
     */
    private static final String SECRET = "mnzxx@2020BJ";
    /**
     * token 过期时间: 默认分钟
     */
    private static final int EXPIRE_TIME = 360;
    /**
     * token 版本号
     */
    private static final int TOKEN_VERSION = 1;

    /**
     * 根据传入的appId以及用户uid创建token信息
     *
     * @author zhoukai
     * @date 2020/7/2 17:20
     */
    public static String createToken(Long uid) {
        if (ObjectUtils.isEmpty(uid)) {
            return null;
        }
        //获取当前时间戳
        long curTime = System.currentTimeMillis();
        //签发日期
        Date iatDate = LocalDateTimeUtils.longToDate(curTime);
        //过期时间
        Date expiresDate = LocalDateTimeUtils.addMinutes(curTime, EXPIRE_TIME);

        // header Map
        Map<String, Object> map = new HashMap<>(2);
        map.put("alg", "HS256");
        map.put("typ", "JWT");
        // build token
        String token = JWT.create().withHeader(map)
                .withClaim("version", TOKEN_VERSION)
                .withClaim("uid", uid)
                .withIssuedAt(iatDate)
                .withExpiresAt(expiresDate)
                .sign(Algorithm.HMAC256(SECRET));
        return token;
    }

    /**
     * 校验token是否有效
     *
     * @author zhoukai
     * @date 2019/1/31 15:08
     */
    public static Map<String, Claim> verifyToken(String token) throws Exception {
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT jwt = verifier.verify(token);
        return jwt.getClaims();
    }

    /**
     * 解析token信息
     *
     * @author zhoukai
     * @date 2019/1/31 15:08
     */
    public static Token parseToken(String token) throws Exception {
        Map<String, Claim> claims = verifyToken(token);
        if (ObjectUtils.isEmpty(claims)) {
            return null;
        }
        Token tokenInfo = new Token();
        Claim uidClaim = claims.get("uid");
        if (!ObjectUtils.isEmpty(uidClaim)) {
            tokenInfo.setUid(uidClaim.asLong());
        }
        Claim versionClaim = claims.get("version");
        if (!ObjectUtils.isEmpty(versionClaim)) {
            tokenInfo.setVersion(versionClaim.asInt());
        }
        Claim iatClaim = claims.get("iat");
        if (!ObjectUtils.isEmpty(iatClaim)) {
            tokenInfo.setIssueTime(iatClaim.asDate());
        }
        Claim expClaim = claims.get("exp");
        if (!ObjectUtils.isEmpty(expClaim)) {
            tokenInfo.setExpireTime(expClaim.asDate());
        }
        return tokenInfo;
    }

    public static void main(String[] args) throws Exception {
        String token = createToken(1000L);
        System.out.println(token);
        Token tokenInfo = parseToken(token);
        System.out.println(tokenInfo);
    }

}
